import { Input, InputNumber, Message, Radio, Select, TreeSelect } from '@arco-design/web-react';
import { useEffect, useState } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import componentsMap from '@src/router';
import DetailItem from '@src/components/detailItem';
import DetailModal from '@src/components/detailModal';
import LoadingMask from '@src/components/loadingMask';
import { createStoreDetailKey, detailRequest, detailUpdate } from '../../../redux/detailReducer';
import { createStoreListKey, listRequest } from '../../../redux/listReducer';
import { AppStore, Record, RecordList, ValidateRule } from '../../../types';
import { cloneDeep, validateField } from '../../../utils/utils';
import IconSelect from './components/IconSelect';
import { Menu } from './types';
import { IconNameType } from '@src/components/svg/svgIcon';

interface Props {
  parentId?: number;
  id: string;
  onCancel: (update?: boolean) => void;
}

const model = 'system';
const table = 'menu';

// 字段验证规则
const rule: ValidateRule = {
  menuName: { required: true, message: '菜单名称必填' },
  orderNum: { required: true, number: true, message: '菜单排序必填' },
};

export default function MenuDetailPage({ id, parentId, onCancel }: Props) {
  // 页面标题 显示在二级菜单下面
  const pageTitle = (id === 'create' ? '新增' : '修改') + '菜单';
  const dispatch = useDispatch();
  // 每次编辑时修改的数据
  const [detailData, setDetailData] = useState<Menu | null | undefined>({
    menuType: 'M',
    parentId: parentId ?? '0',
    status: '0',
    visible: '0',
  });

  // 数据验证结果
  const [errorData, setErrorData] = useState<{ [x: string]: string }>({});
  // --------------额外数据--------------------------------------
  // -----------------------------------------------------------
  // 当前详情 根据id的值区分页面模式
  const { detail, menuList }: { detail?: Record<Menu>; menuList?: RecordList<Menu> } = useSelector(
    (state: AppStore) => {
      let _detail;
      if (id !== 'create') {
        _detail = state.detail?.[createStoreDetailKey({ model, table, id })];
      }

      let _menuList = state.list?.[createStoreListKey({ model, table })];

      return {
        detail: _detail,
        menuList: _menuList,
      };
    },
    shallowEqual
  );

  // 页面初次渲染时获取数据
  useEffect(() => {
    if (id && id !== 'create') {
      handleRefreshData();
    }
    dispatch(listRequest({ model, table })); //  card/product/type/list
  }, []); //eslint-disable-line

  // 页面详情数据获取到后存入编辑数据
  useEffect(() => {
    if (id !== 'create' && detail?.loaded && detail?.result && !detailData?.menuId) {
      let result = detail?.result;
      setDetailData(result);
      // 需要依赖详情数据加载别的数据的 在这里写
    }
  }, [detail]); //eslint-disable-line

  // 当前详情数据请求
  function handleRefreshData(forceRefresh?: boolean) {
    if (id && id !== 'create') {
      dispatch(detailRequest({ model, table, id, forceRefresh }));
    }
  }
  // 任意字段修改时存入编辑数据
  function handleChange(key: string, value: any) {
    setErrorData({});

    let data: any = cloneDeep(detailData);
    data[key] = value;
    setDetailData(data);
  }

  async function handleSave() {
    let validateRes = validateField(detailData, rule);
    setErrorData(validateRes);
    if (Object.keys(validateRes).length) return;

    LoadingMask.show('正在保存...');
    dispatch(
      detailUpdate({
        model,
        table,
        id,
        detail: detailData,
        callback(code, msg) {
          LoadingMask.hide();
          let _msg = code === 200 ? Message.success : Message.warning;
          _msg(msg ?? '');
          if (code === 200) {
            onCancel(true);
          }
        },
      })
    );
  }

  //----------------额外操作 / 数据-------------------
  // 上级菜单树
  let parentList: Menu[] = menuList?.results || [];
  parentList = parentList.filter((i) => i.menuType !== 'F');
  type TreeSelectDataType = {
    title: string;
    key: string;
    parentId?: number | string;
    children?: TreeSelectDataType[];
  };
  let map: { [x: string]: TreeSelectDataType } = {};
  parentList.forEach((i) => {
    map[i.menuId?.toString() ?? ''] = {
      title: i.menuName!,
      key: i.menuId!.toString(),
      parentId: i.parentId,
      children: [],
    };
  });
  Object.keys(map).forEach((i) => {
    let data = map[i];
    if (data.parentId && map[data.parentId?.toString() ?? '']) {
      map[data.parentId?.toString() ?? ''].children!.push(data);
    }
  });

  let treeList: TreeSelectDataType[] = [];

  Object.keys(map).forEach((i) => {
    let data = map[i];
    if (!data.parentId) {
      treeList.push(data);
    } else if ((data.children?.length ?? 0) <= 0) {
      delete data.children;
    }
  });
  treeList = [{ title: '根目录', key: '0', children: treeList }];

  //组件地址
  let componentPath: Array<{ label: string; value: string }> = [];
  Object.keys(componentsMap).forEach((key) => {
    if (!key.includes('/detail')) {
      componentPath.push({ label: key, value: key });
    }
  });
  //-------------------------------------------------

  return (
    <DetailModal
      title={pageTitle}
      show
      onConfirm={handleSave}
      onCancel={() => onCancel()}
      className="minw-700"
      contentClassName="minh-500 ac-start"
    >
      <DetailItem label="上级菜单" labelSpan={8} outlet={2} error={errorData.parentId}>
        <TreeSelect
          className="m-tree-select"
          value={detailData?.parentId?.toString()}
          treeData={treeList}
          onChange={(v) => handleChange('parentId', v)}
        />
      </DetailItem>
      <DetailItem label="菜单类型" labelSpan={8} outlet={2} error={errorData.menuType}>
        <Radio.Group value={detailData?.menuType} onChange={(v) => handleChange('menuType', v)}>
          <Radio value={'M'}>目录</Radio>
          <Radio value={'C'}>菜单</Radio>
          <Radio value={'F'}>按钮</Radio>
        </Radio.Group>
      </DetailItem>
      <DetailItem label="菜单名称" required labelSpan={8} outlet={2} error={errorData.menuName}>
        <Input className="m-input" value={detailData?.menuName} onChange={(v) => handleChange('menuName', v)} />
      </DetailItem>
      <DetailItem label="显示排序" required labelSpan={8} outlet={2} error={errorData.orderNum}>
        <InputNumber className="m-input" value={detailData?.orderNum} onChange={(v) => handleChange('orderNum', v)} />
      </DetailItem>
      {detailData?.menuType !== 'F' && (
        <DetailItem label="图标" labelSpan={8} outlet={2} error={errorData.icon}>
          <IconSelect value={detailData?.icon as IconNameType} onChange={(v) => handleChange('icon', v)} />
        </DetailItem>
      )}
      {detailData?.menuType !== 'F' && (
        <DetailItem label="路由地址" labelSpan={8} outlet={2} error={errorData.path}>
          <Input className="m-input" value={detailData?.path} onChange={(v) => handleChange('path', v)} />
        </DetailItem>
      )}
      {detailData?.menuType === 'C' && (
        <DetailItem label="路由参数" labelSpan={8} outlet={2} error={errorData.queryParam}>
          <Input className="m-input" value={detailData?.queryParam} onChange={(v) => handleChange('queryParam', v)} />
        </DetailItem>
      )}
      {detailData?.menuType === 'C' && (
        <DetailItem label="组件地址" labelSpan={8} outlet={2} error={errorData.component}>
          <Select
            className="m-select"
            allowClear
            showSearch
            value={detailData?.component}
            options={componentPath}
            onChange={(v) => handleChange('component', v)}
          />
        </DetailItem>
      )}
      {detailData?.menuType !== 'M' && (
        <DetailItem label="权限标识" labelSpan={4} outlet={4} error={errorData.perms}>
          <Input className="m-input" value={detailData?.perms} onChange={(v) => handleChange('perms', v)} />
        </DetailItem>
      )}

      <DetailItem label="备注" labelSpan={4} outlet={4} error={errorData.remark}>
        <Input.TextArea
          className="m-input-area"
          maxLength={200}
          showWordLimit
          value={detailData?.remark}
          autoSize={{ minRows: 4 }}
          onChange={(v) => handleChange('remark', v)}
        />
      </DetailItem>
    </DetailModal>
  );
}
